package org.example.chatservice.filter;

import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

@Component
public class SensitiveWordFilter {
    private TrieNode rootNode;

    @PostConstruct
    public void init() {
        rootNode = new TrieNode();
        loadSensitiveWords();
    }

    private void loadSensitiveWords() {
        try {
            InputStream is = getClass().getResourceAsStream("/sensitive-words.txt");
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String word;
            while ((word = reader.readLine()) != null) {
                addWord(word.trim());
            }
            reader.close();
        } catch (Exception e) {
            throw new RuntimeException("Failed to load sensitive words", e);
        }
    }

    private void addWord(String word) {
        TrieNode node = rootNode;
        for (char c : word.toCharArray()) {
            node.children.putIfAbsent(c, new TrieNode());
            node = node.children.get(c);
        }
        node.isEndOfWord = true;
    }

    public String filter(String text) {
        if (text == null || text.isEmpty()) {
            return text;
        }

        StringBuilder result = new StringBuilder(text);
        int i = 0;
        while (i < text.length()) {
            int length = findSensitiveWord(text, i);
            if (length > 0) {
                for (int j = i; j < i + length; j++) {
                    result.setCharAt(j, '*');
                }
                i += length;
            } else {
                i++;
            }
        }
        return result.toString();
    }

    private int findSensitiveWord(String text, int start) {
        TrieNode node = rootNode;
        int length = 0;
        int maxLength = 0;

        for (int i = start; i < text.length(); i++) {
            char c = text.charAt(i);
            node = node.children.get(c);
            if (node == null) {
                break;
            }
            length++;
            if (node.isEndOfWord) {
                maxLength = length;
            }
        }
        return maxLength;
    }

    private static class TrieNode {
        Map<Character, TrieNode> children = new HashMap<>();
        boolean isEndOfWord;
    }
}